Function.prototype.WApply = function (thisArg, otherArgs) {
  thisArg =
    thisArg === undefined || thisArg === null ? window : Object(thisArg);

  Object.defineProperty(thisArg, "fn", {
    writable: false,
    enumerable: false,
    configurable: true,
    value: this,
  });

  thisArg.fn(...otherArgs);

  delete thisArg.fn;
};

Function.prototype.WCall = function (thisArg, ...otherArgs) {
  thisArg =
    thisArg === undefined || thisArg === null ? window : Object(thisArg);

  Object.defineProperty(thisArg, "fn", {
    writable: false,
    enumerable: false,
    configurable: true,
    value: this,
  });

  thisArg.fn(...otherArgs);

  delete thisArg.fn;
};

Function.prototype.WBind = function (thisArg, otherArgs) {
  thisArg =
    thisArg === undefined || thisArg === null ? window : Object(thisArg);

  Object.definePrototype(thisArg, "fn", {
    writable: false,
    enumerable: false,
    configurable: true,
    value: this,
  });

  return (...args) => {
    let allArg = [...otherArgs, ...args];
    thisArg.fn(...allArg);
  };
};
